// 通过express基本写法开启一个服务器
const express = require('express');
let app = express();
const { TOKENPWD } = require('./util/config');

// 静态资源托管
app.use('/uploads', express.static('uploads'));

// 定义内置中间件来接收相关的请求报文体参数
app.use(express.urlencoded());
app.use(express.json());

// 设定cors跨域
const cors = require('cors');
app.use(cors());

var jwt = require('express-jwt');
// 全局注册中间件
app.use(jwt({
    secret: TOKENPWD, // 加密的密码要和token生成时的密码保持一致
    algorithms: ['HS256']  // 这个是加密算法，如果不写则报错
}).unless({
    path: ['/user/login', '/user/register']  // 排除token验证的路径
}));

// 通过自定义的全局中间件将execSql方法挂载到res对象上
// 将来，在所有的路由处理函数的res对象上就可以直接使用execSql方法了
const execSql = require('./util/sql.js');
app.use((req, res, next) => {
    // 将execSql方法挂载到res对象上
    res.execSql = execSql;
    next();//触发下一个函数的执行
})


// 导入相关的路由中间件并且注册
const userRouter = require('./router/user_router');
const heroRouter = require('./router/hero_router');
// 注册路由中间件
app.use('/user', userRouter);
app.use('/hero', heroRouter);


// 利用错误中间件统一处理token验证失败的异常
app.use(function (err, req, res, next) {
    // 如果err.name是UnauthorizedError 表示token验证失败了
    if (err.name === 'UnauthorizedError') {
        // 响应身份认证失败的json格式，其中code=401表示没有登录
        res.status(200).send({ code: 401, msg: '身份验证失败，请重新登录' });
    }
});

app.listen(3001, () => {
    console.log('3001英雄接口服务器启动');
})